#include "stdafx.h"

#include "..\inc\Page.h"
#include "..\inc\pagemanager.h"
#include "..\inc\PageContentCollection.h"
#include "..\inc\PageContentCollectionFactory.h"
#include "..\inc\PageWorldSection.h"
#include "..\inc\PageStrategy.h"

#include "..\inc\pageworld.h"

using namespace PageSystem;

PageManager::PageManager()
{
}

PageManager::~PageManager()
{
}

PagedWorld* PageManager::createWorld(const String& name )
{
	WorldMap::iterator pos = mWorlds.find( name );
	//the name already exists
	if( pos != mWorlds.end() )
		return (*pos).second;
	//create a new one and add to the map
	PagedWorld* pNewPageWorld = new PagedWorld( name , this );
	mWorlds.insert( WorldMap::value_type( name , pNewPageWorld ) );

	return pNewPageWorld;
}

void PageManager::destroyWorld(const String& name)
{
	WorldMap::iterator pos = mWorlds.find( name );
	if( pos != mWorlds.end() )
	{
		delete (*pos).second;
		mWorlds.erase( pos );
	}
}

void PageManager::addContentCollectionFactory(PageContentCollectionFactory* f)
{
	assert( f != NULL );
	if( f == NULL )
		return;

	ContentCollectionFactoryMap::iterator pos = mContentCollectionFactories.find( f->getName() );
	//the factory exists
	if( pos != mContentCollectionFactories.end() )
		return;

	mContentCollectionFactories.insert( ContentCollectionFactoryMap::value_type( f->getName() , f ) );
}

void PageManager::removeContentCollectionFactory(PageContentCollectionFactory* f)
{
	assert( f != NULL );
	if( f == NULL )
		return;

	ContentCollectionFactoryMap::iterator pos = mContentCollectionFactories.find( f->getName() );
	//the factory exists
	if( pos != mContentCollectionFactories.end() )
	{
		delete (*pos).second;
		mContentCollectionFactories.erase( pos );
	}
}

/** Get a PageContentCollectionFactory.
@param name The name of the factory to retrieve
@returns Pointer to a PageContentCollectionFactory, or null if the ContentCollection was not found.
*/
PageContentCollectionFactory* PageManager::getContentCollectionFactory(const String& name)
{
	ContentCollectionFactoryMap::iterator pos = mContentCollectionFactories.find( name );
	//the factory exists
	if( pos == mContentCollectionFactories.end() )
		return NULL;

	return pos->second;
}

/** Get a reference to the registered strategies.
*/
const PageManager::ContentCollectionFactoryMap& PageManager::getContentCollectionFactories() const
{
	return mContentCollectionFactories;
}

PageContentCollection* PageManager::createContentCollection(const String& typeName)
{
	PageContentCollectionFactory* pFactory = this->getContentCollectionFactory( typeName );
	if( pFactory == NULL )
		return NULL;

	PageContentCollection* pContentCollection = pFactory->createInstance();
	return pContentCollection;
}

/** Destroy an instance of PageContentCollection. */
void PageManager::destroyContentCollection(PageContentCollection* coll)
{
	assert( coll != NULL );
	if( coll == NULL )
		return;
	//ContentCollectionFactoryMap::iterator pos = std::find_if( mContentCollectionFactories.begin() , mContentCollectionFactories.end() , std::bind2nd( std::equal_to<PageContentCollection*>( ) , coll ) );

	PageContentCollectionFactory* pFactory = this->getContentCollectionFactory( coll->getType() );
	if( pFactory == NULL )
		return;

	delete coll;
}

PagedWorldSectionFactory* PageManager::getWorldSectionFactory(const String& name)
{
	WorldSectionFactoryMap::iterator pos = mWorldSectionFactories.find( name );
	if ( pos == mWorldSectionFactories.end() )
		return NULL;

	return pos->second;
}

void PageManager::addWorldSectionFactory(PagedWorldSectionFactory* f)
{
	assert( f != NULL );
	if( f == NULL )
		return;

	PagedWorldSectionFactory* pPageWorldSectionFactory = this->getWorldSectionFactory( f->getName() );
	if( pPageWorldSectionFactory != NULL )
		return;

	mWorldSectionFactories.insert( WorldSectionFactoryMap::value_type(  f->getName() , f ) );
}

void PageManager::removeWorldSectionFactory(PagedWorldSectionFactory* f)
{
	WorldSectionFactoryMap::iterator pos = mWorldSectionFactories.find( f->getName() );
	if ( pos == mWorldSectionFactories.end() )
		return;

	delete f;
	mWorldSectionFactories.erase( pos );
}

void PageManager::addStrategy(PageStrategy* strategy)
{
	if( this->getStrategy( strategy->getName() ) != NULL )
		return;

	mStrategies.insert( StrategyMap::value_type( strategy->getName() , strategy ) );
}

void PageManager::removeStrategy(PageStrategy* strategy)
{
	StrategyMap::iterator pos = mStrategies.find( strategy->getName() );
	if( pos == mStrategies.end() )
		return;

	delete pos->second;
	mStrategies.erase( pos );
}

PageStrategy* PageManager::getStrategy(const String& name)
{
	StrategyMap::iterator pos = mStrategies.find( name );
	if( pos == mStrategies.end() )
		return NULL;

	return pos->second;
}

const PageManager::StrategyMap& PageManager::getStrategies() const
{
	return mStrategies;
}
